package com.youlu.campus.service.notify;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;

import com.youlu.campus.common.utils.HttpClientUtil;
import com.youlu.campus.common.utils.Md5Utils;
import com.youlu.campus.entity.DeliveryOrderItem;
import com.youlu.campus.entity.OOrderInfo;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.SFLuYouLog;
import com.youlu.campus.entity.VO.SFWaybillSubmitLog;
import com.youlu.campus.entity.VO.req.ShunFengOrderVO;
import com.youlu.campus.entity.VO.res.SFCallbackBody;
import com.youlu.campus.entity.VO.res.SFCallbackItemRes;
import com.youlu.campus.entity.VO.res.SFCallbackRes;
import com.youlu.campus.entity.VO.res.SFResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ShunFengService {

    @Value("${kuaidi.shunfeng.appId}")
    private String appId;

    @Value("${kuaidi.shunfeng.appSecret}")
    private String appSecret;

    @Value("${kuaidi.shunfeng.url}")
    private String url;
    @Autowired
    private org.springframework.data.mongodb.core.MongoTemplate mongoTemplate;


    public SFWaybillSubmitLog shunFengOrder(ShunFengOrderVO shunFengOrder) {
        log.info("开始同步订单->{} 到顺丰", JSON.toJSONString(shunFengOrder));
        Map<String, Object> mapData = JSON.parseObject(JSON.toJSONString(shunFengOrder), Map.class);
        TreeMap<String, Object> paramBodyMap = new TreeMap(mapData);
        log.info("开始同步订单 参数处理排序->{}", JSON.toJSONString(paramBodyMap));
        String sign = Md5Utils.encrypt32(appId + appSecret + JSON.toJSONString(paramBodyMap));
        Map<String, Object> paramMap = new HashMap(4);
        paramMap.put("appId", appId);
        paramMap.put("appSecret", appSecret);
        paramMap.put("json", JSON.toJSONString(paramBodyMap));
        paramMap.put("sign", sign);
        String formUrl = url + "/api2/OrderService";
        try {
            String result = HttpClientUtil.postForm(formUrl, paramMap, null, 3000, "utf8", 3, true);
            log.info("同步订单->{}返回结果", result);
            if (StringUtils.isBlank(result)) {
                return null;
            }
            SFResult sfResult = JSON.parseObject(result, SFResult.class);
            if (!sfResult.getCode().equals(200)) {
                log.error("同步订单错误->{}返回结果", sfResult.getMsg());
                return null;
            }
            String json = sfResult.getJson();
            if (StringUtils.isNotBlank(json)) {
                SFWaybillSubmitLog sfWaybillSubmitLog = JSON.parseObject(json, SFWaybillSubmitLog.class);
                if (Objects.isNull(sfWaybillSubmitLog)) {
                    return null;
                }
                if (Objects.nonNull(sfWaybillSubmitLog.getFilterResult()) && sfWaybillSubmitLog.getFilterResult() == 3) {
                    log.error("同步订单错误->{} 不可收派 备注信息->{} ", sfWaybillSubmitLog.getOrderId(), sfWaybillSubmitLog.getRemark());
                    return null;
                }
                sfWaybillSubmitLog.setResultJson(result);
                return sfWaybillSubmitLog;
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("同步订单错误->{}", e);
            return null;
        }catch (Exception e) {
            e.printStackTrace();
            log.error("同步订单错误->{}", e);
            return null;
        }
        return null;
    }


    public void callback(SFCallbackRes sfCallback) {
        log.info("顺丰请求回掉接口 sfCallback  json - >{}", JSON.toJSONString(sfCallback));
        SFCallbackBody sfBody = sfCallback.getBody();
        if (Objects.isNull(sfBody)) {
            return;
        }
        List<SFCallbackItemRes> waybillRouteList = sfBody.getWaybillRoute();
        if (CollectionUtils.isEmpty(waybillRouteList)) {
            return;
        }
        List<SFLuYouLog> list = waybillRouteList.stream().map(sfCallbackItemRes -> {
            SFLuYouLog sfLuYouLog = new SFLuYouLog();
            BeanUtils.copyProperties(sfCallbackItemRes, sfLuYouLog);
            sfLuYouLog.setId(null);
            sfLuYouLog.setLuYouId(sfCallbackItemRes.getId());
            return sfLuYouLog;
        }).collect(Collectors.toList());
        this.mongoTemplate.insertAll(list);
        SFLuYouLog sfLuYouLog = list.get(0);
        //更新订单
        updateOrder(sfLuYouLog.getOrderId(), sfLuYouLog.getMailNo());
    }

    @Async
    public void updateOrder(String subOrderNo, String mailNo) {
        Query query = new Query();
        query.addCriteria(Criteria.where("status").is("3"));
        query.addCriteria(Criteria.where("oOrderNo").is(subOrderNo));
        OOrderInfo subOrder = this.mongoTemplate.findOne(query, OOrderInfo.class);
        if (Objects.isNull(subOrder)) {
            log.error(":>>> 更新顺丰子订单不存在:{}", subOrderNo);
            return;
        }
        Date now = new Date();
        //更新子订单待收货
        Update update = new Update();
        update.set("status", "4");
        update.set("logisticsNo", mailNo);
        update.set("logisticsCompany", "邮政航空EMS");
        update.set("updatedTime", now);
        update.set("deliveryTime", now);
        this.mongoTemplate.updateFirst(query, update, OOrderInfo.class);
        // 更新合单其他订单物流单号
        this.updateSingleOrder(subOrder);
        query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(subOrder.getOrderNo()));
        query.addCriteria(Criteria.where("status").is("3"));
        //更新主订单订单待收货
        update = new Update();
        update.set("status", "4");
        update.push("logisticsNos", mailNo);
        update.set("logisticsCompany", "邮政航空EMS");
        update.set("deliveryTime", now);
        update.set("updatedTime", now);
        this.mongoTemplate.updateFirst(query, update, OrderInfo.class);
        //更新子订单号快递编号
        query = new Query();
        query.addCriteria(Criteria.where("subOrderNo").is(subOrderNo));
        query.addCriteria(Criteria.where("expressNumber").is(mailNo));
        update = new Update();
        update.set("deliveryStatus", "delivered");
        update.set("deliveryTime", now);
        update.set("updatedTime", now);
        this.mongoTemplate.updateFirst(query, update, DeliveryOrderItem.class);
    }

    private void updateSingleOrder(OOrderInfo sub) {
        log.info(":>>> 顺丰更新物流接口:{} 同步更新物流单号", sub == null ? null : sub.getId());
        if (Objects.isNull(sub) || StringUtils.isBlank(sub.getSingleNo()) || StringUtils.isBlank(sub.getLogisticsNo())) {
            log.info(":>>> 顺丰更新物流接口,没有合单号不需要更新其他订单");
            return;
        }
        Date date = new Date();
        Query query = new Query().addCriteria(Criteria.where("singleNo").is(sub.getSingleNo()).and("id").ne(sub.getId()));
        Update update = new Update();
        update.set("logisticsNo", sub.getLogisticsNo());
        update.set("logisticsCompany", sub.getLogisticsCompany());
        update.set("updatedTime", date);
        UpdateResult result = mongoTemplate.updateMulti(query, update, OOrderInfo.class);
        log.info(":>>> 更新合单号:{} 物流公司:{},单号:{},数量为:{}", sub.getSingleNo(), sub.getLogisticsCompany(),
                sub.getLogisticsNo(), result.getModifiedCount());
    }


    public static void main(String[] args) {
        String appId = "SF-fa20932511774f74b382885e3bf30343";
        String appSecret = "9bb4820a751543c1ac0fa9a63fc7ac74";
        String json = "{\"msg\":\"下单成功\",\"json\":{\"mailNo\":\"SF7444435142336\",\"mappingMark\":null," +
                "\"destCode\":\"734\",\"orderId\":\"20210824223841455917-762471\",\"filterResult\":\"2\"," +
                "\"agentMailNo\":null,\"originCode\":\"010\",\"remark\":null," +
                "\"orderResponseRlsInfoList\":[{\"rlsCode\":\"1000\",\"errorDesc\":null," +
                "\"orderResponseRlsDetail\":{\"proCode\":\"T4\",\"codingMapping\":\"734AG\",\"errMsg\":null," +
                "\"destRouteLabel\":\"734AG-016\",\"limitTypeCode\":\"T4\",\"sourceCityCode\":\"010\"," +
                "\"destPortCode\":null,\"destCityCode\":\"734\",\"newIcon\":null,\"destTeamCode\":\"016\"," +
                "\"goodsNumber\":null,\"codingMappingOut\":null,\"printIcon\":\"00000000\",\"proName\":\"顺丰特快\"," +
                "\"sourceTeamCode\":null,\"destDeptCodeMapping\":null,\"twoDimensionCode\":\"MMM={'k1':'734W'," +
                "'k2':'734AG','k3':'016','k4':'T4','k5':'SF7444435142336','k6':'','k7':'b9753f37'}\",\"abFlag\":null," +
                "\"printFlag\":\"000000000\",\"currencySymbol\":null,\"goodsValueTotal\":null," +
                "\"sourceDeptCode\":\"010\",\"cargoTypeCode\":\"C201\",\"checkCode\":\"b9753f37\"," +
                "\"destCountry\":null,\"destDeptCode\":\"734AG\",\"sourceTransferCode\":null," +
                "\"destTransferCode\":\"734W\",\"destTeamCodeMapping\":null,\"expressTypeCode\":\"B1\"," +
                "\"xbFlag\":\"0\",\"destPostCode\":null,\"waybillNo\":\"SF7444435142336\"},\"invokeResult\":\"OK\"}]," +
                "\"returnTrackingNo\":null,\"url\":null},\"code\":200}";
        SFResult result = JSON.parseObject(json, SFResult.class);
        System.out.println(result.getCode());

    }

}
